#ifndef SIMPHYSICS_H
#define SIMPHYSICS_H

#include "LinearMath/btAlignedObjectArray.h"
#include "bulletdebugdrawer.h"

// Forward declarations
class btTransform;
class btBroadphaseInterface;
class btCollisionShape;
//class btOverlappingPairCache;
class btCollisionDispatcher;
class btConstraintSolver;
//struct btCollisionAlgorithmCreateFunc;
class btDefaultCollisionConfiguration;
class    btDynamicsWorld;
class    btRigidBody;
class    btTypedConstraint;

/*
 * This class hosts the bullet physics world. It should have minimal(if any) rendering code.
 * Certainly no Qt code. It will be brought under the Physics Abstraction Layer later on.
 *
 * Physics objects will be developed later and they will respond to key input.
 *
 */
class SimPhysics
{
public:
    SimPhysics();
    virtual ~SimPhysics();

    /*
     * Initialize physics
     */
    virtual    void initPhysics();

    /*
     * Step the physics
     */
    virtual void stepPhysics();

    /*
     * Reset
     */
    virtual void SimPhysics::resetScene();

    /*
     * End it !
     */
    virtual    void exitPhysics();

    /*
     * Get time difference
     */
    btScalar    getDeltaTimeMicroseconds()
    {
#ifdef USE_BT_CLOCK
        btScalar dt = (btScalar)mClock.getTimeMicroseconds();
        mClock.reset();
        return dt;
#else
        return btScalar(16666.);
#endif
    }

    /*
     * Create rigid bodies - check Bump's impl
     */
    btRigidBody* localCreateRigidBody(float mass,
                                      const btTransform& startTransform,
                                      btCollisionShape* shape);

    //Rigid body management
/*    btRigidBody* addRigidBody(float mass, const btTransform& startTransform,btCollisionShape* shape,
            btVector3& bodyInertia = BTZEROVECTOR);
    btRigidBody* addKinematicBody(btScalar mass, const btTransform& startTransform,btCollisionShape* shape);*/

    /*
     * Debugging support. This should be done through a single function that takes a complexity
     * parameter and sets up scenes of different complexities. Can be useful for unit testing too.
     *
     *
     */
    void setupDebuggingScene(int complexity);
    void setupLevel1Scene(void);
    void setupLevel2Scene(void);

    /* Get debug drawer, added to enable renderer to get the vertices of the drawn lines */
    BulletDebugDrawer& getDebugDrawer(void)
    {
        return mDebugDrawer;
    }

    /*
     * Rendering the scene
     */
    virtual void render();

private:
    // Keep the collision shapes, for deletion/cleanup
    btAlignedObjectArray<btCollisionShape*> mCollisionShapes;

    btBroadphaseInterface* mBroadphase;
    btCollisionDispatcher* mDispatcher;
    btConstraintSolver* mSolver;
    btDefaultCollisionConfiguration* mCollisionConfiguration;

    // This is the most important class
    btDynamicsWorld* mDynamicsWorld;

    // This clock IS used - do not delete
    btClock mClock;

    // Constraint for mouse picking
    btTypedConstraint* mPickConstraint;

    // For shooting boxes later
    btCollisionShape* mShootBoxShape;

    // Debugging
    btRigidBody* mFallRigidBody;
    BulletDebugDrawer mDebugDrawer;
};

#endif // SIMPHYSICS_H
